package com.medical.data.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.medical.data.component.LoginUserThreadLocal;
import com.medical.data.domain.User;
import com.medical.data.exception.MyException;
import com.medical.data.mapper.UserMapper;
import com.medical.data.service.FormDataService;
import com.medical.data.service.FormTemplateService;
import com.medical.data.service.TokenSerivce;
import com.medical.data.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medical.data.utils.BCrypt;
import com.medical.data.utils.FileUtils;
import com.medical.data.utils.JwtUtils;
import com.medical.data.utils.ResultCode;
import com.medical.data.vo.LoginUser;
import com.medical.data.vo.UpdatePasswordVo;
import com.medical.data.vo.UserInformationVo;
import com.medical.data.vo.UserLoginVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cj
 * @since 2024-02-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private AuthenticationManager manager;

    @Autowired
    private TokenSerivce tokenSerivce;

    @Autowired
    private FileUtils fileUtils;

    @Autowired
    private FormTemplateService formTemplateService;

    @Override
    public String login(UserLoginVo userLoginVo) {
        //TODO 后续需要在这里对秘密进行解密操作,现在不做
        Authentication authenticate = null;
        try {
            //1.先将密码个用户名进行封装成authentication实现类UsernamePasswordAuthenticationToken对象
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userLoginVo.getUserName(), userLoginVo.getPassword());
            //2.进行认证
            authenticate = manager.authenticate(authenticationToken);
        } catch (AuthenticationException e) {
            throw new MyException(500, e.getMessage());
            //e.printStackTrace();
        }
        //3.查看是否认证成功
        if (authenticate == null) {
            throw new MyException(500, "认证失败");
        }
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        //4.认证成功,获取对象
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        User user = loginUser.getUser();
//        //检查是否被冻结
//        if ("1".equals(user.getUserState())){
//            throw new MyException(500,"用户被冻结,请联系管理员");
//        }
//        //当登录成功以后需要更新登录时间
//        user.setLastLogin(new Date());
//        boolean update = this.updateById(user);
/*        if (!update)
            throw new MyException(500,"用户登录失败");*/
        //生成token
        String jwtToken = JwtUtils.getJwtToken(user.getId(), user.getUserName(), user.getNickName());
        //登录成功,将用户信息存入 key是token,value是loginUser
        loginUser.setToken(jwtToken);
        tokenSerivce.setLoginUser(jwtToken, loginUser);
/*


        LambdaQueryWrapper<User>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserName,loginUser.getUsername());
        User user1=this.baseMapper.selectOne(wrapper);

*/

        return jwtToken;

    }

    @Override
    public User getUserByName(String username) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserName, username)
        ; // 添加条件，is_delete不等于1;

        return this.getOne(lambdaQueryWrapper);
    }

    @Override
    public User getUserById(String id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, id);
        User user = baseMapper.selectOne(wrapper);
        if (ObjectUtils.isNotEmpty(user)) {
            return user;
        } else {
            throw new MyException(ResultCode.ERROR.getCode(), "用户不存在");
        }
    }

    @Override
    public UserInformationVo getUserById() {
        User user = tokenSerivce.getUser();
        User user1 = baseMapper.selectById(user.getId());
        UserInformationVo userInformationVo = new UserInformationVo();
        BeanUtils.copyProperties(user1, userInformationVo);
        return userInformationVo;
    }

    @Override
    public void updateUser(UserInformationVo userInformationVo) {
        String userId = tokenSerivce.getUser().getId();
        User user = new User();
        BeanUtils.copyProperties(userInformationVo, user);
        user.setId(userId);
        baseMapper.updateById(user);
    }

    @Override
    public void updateAvatar(MultipartFile file, String name) {
        User user = tokenSerivce.getUser();
        String avatar = fileUtils.uploadImage(file, name);
/*        System.out.println("==================="+avatar);
        LambdaUpdateWrapper<User>wrapper=new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId,user.getId());*/
        user.setAvatar(avatar);
        int update = baseMapper.updateById(user);
        if (update < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "上传头像失败");
        }
    }

    @Override
    public void reg(UserLoginVo userLoginVo) {
        //首先判断该用户名称是否存在
        User user1 = baseMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUserName, userLoginVo.getUserName()).select(User::getId));
        if (user1 != null) {
            throw new MyException(ResultCode.ERROR.getCode(), "该用户已存在");
        }
        String password = BCrypt.hashpw(userLoginVo.getPassword(), BCrypt.gensalt());
        //添加用户
        User user = new User().setUserName(userLoginVo.getUserName()).setPassword(password);
        int insert = baseMapper.insert(user);
        if (insert < 1) {
            throw new MyException(ResultCode.ERROR.getCode(), "用户注册失败");
        }
//        BCrypt.hashpw()
    }

    @Override
    public List<User> getUserByDepartmentId(String departmentId) {
        List<User> users = baseMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getDepartmentId, departmentId).orderByDesc(User::getNickName));
        return users;

    }

    @Override
    public void updatePassword(UpdatePasswordVo updatePasswordVo) {
        User user = tokenSerivce.getUser();
        //判断两次输入的输入的密码是否一致
        if (!StringUtils.equals(updatePasswordVo.getNewPassword(), updatePasswordVo.getNewEnterPassword())) {
            throw new MyException(ResultCode.ERROR.getCode(), "两次输入的密码不一致");
        }
        User user1 = baseMapper.selectById(user.getId());
        if (!BCrypt.checkpw(updatePasswordVo.getOldPassword(), user1.getPassword())) {
            throw new MyException(ResultCode.ERROR.getCode(), "旧密码输入有误");
        }
        User user2 = new User().setId(user1.getId()).setPassword(BCrypt.hashpw(updatePasswordVo.getNewPassword(), BCrypt.gensalt()));
        int i = baseMapper.updateById(user2);
        if (i < 1)
            throw new MyException(ResultCode.ERROR.getCode(), "更新密码失败");

    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        return null;
    }

    @Override
    public int getUserNumber() {
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getHsId, user.getHsId());
        return this.baseMapper.selectList(wrapper).size();
    }

    @Override
    public int getTodayUserNumber() {
        LocalDate today = LocalDate.now();
        User user = tokenSerivce.getUser();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getHsId, user.getHsId())
                .apply("DATE(create_time) = DATE({0})", today); // 使用DATE()函数比较日期部分;;
        return this.baseMapper.selectList(wrapper).size();
    }

    @Override
    public List<User> getUserByHs(String id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getHsId, id);
        return this.baseMapper.selectList(wrapper);
    }

    @Override
    public int getDataNumber(String id) {
        return formTemplateService.getFormDataNumberByUser(id);
    }

    @Override
    public List<User> getUserByKs(String id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getDepartmentId, id);
        return this.baseMapper.selectList(wrapper);
    }

}
